package com.borya.userauth;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.borya.framework.core.*;
import com.borya.framework.util.ObjectUtils;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.borya.model.db.Flag;
import com.borya.model.db.PackageInfo;
import com.borya.model.db.User;
import com.borya.model.entity.HeaderEntity;
import com.borya.statuscode.StatusCode;

/**
 * 用户鉴权,强制升级
 * 
 * @author borya
 *
 */
public final class UserAuthManager {

	private Logger log = Logger.getLogger(getClass());
	private ServerSqlSessionFactory sqlDataSource;
	private int TMSI_EXPIRED_HOUR;
	private String LATEST = "latest";
	private UserAuthManager() {
	}

	private static final class UserCheckManagerHolder {
		private final static UserAuthManager instance = new UserAuthManager();
	}

	public static final UserAuthManager getInstance() {
		return UserCheckManagerHolder.instance;
	}

	private ServerSqlSessionFactory getSqlDataSource() {
		return sqlDataSource;
	}

	private ServerRedisSessionFactory sessionFactory;

	public ServerRedisSessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void init(ServerSqlSessionFactory sqlDataSource, int tmsi_expired_hour,
					 ServerRedisSessionFactory sessionFactory) {
		this.sqlDataSource = sqlDataSource;
		this.sessionFactory = sessionFactory;
		TMSI_EXPIRED_HOUR = tmsi_expired_hour;

		Boolean bool = testConn();
		if (bool == null) {
			System.err.println("DB Connection exception.");
			log.warn("DB Connection exception.");
		} else {
			log.info("DB Connection successed.");
		}
	}

	public final Object doPrepare(Map<String, String> map,final HeaderEntity authHeader) {
		final String url = map.get("url");
		final String host = map.get("host");
		final String tmsiStr = map.get("tmsi");
		final String userId = map.get("userId");
		final String latitude = map.get("latitude");
		final String longitude = map.get("longitude");
		final String appVersion = map.get("appVersion");
		final String packageName = map.get("packageName");
		final int osType = Integer.valueOf(map.get("osType"));
		final String imei = map.get("imei");
		final String locationFlag = map.get("locationFlag");
		if (userId == null) {
			log.warn("userId is empty,userid=" + userId+",url="+url);
			return StatusCode.USER_NOT_FOUND.toJSON();
		}
		if (tmsiStr == null || tmsiStr.trim().length() == 0) {
			log.warn("tmsi is empty,userid=" + userId+",url="+url);
			return StatusCode.TMSI_NO_MATCH.toJSON("用户信息过期,请重新登录");
		}
		if(ObjectUtils.isEqual("0",tmsiStr)){
			log.warn("请求tmsi为0，"+map);
			return StatusCode.TMSI_NO_MATCH.toJSON("用户信息过期,请重新登录");
		}

//		User user;
//		final String synchroKey = "ka_meng:synchro:user:" + userId;
//		String synchroUserStr = redis_get(synchroKey);
//		if(ObjectUtils.nonNullOrEmpty(synchroUserStr)){
//			user = JSONObject.parseObject(synchroUserStr,User.class);
//		}
//		else{
//			user = getUser(userId);
//		}
		User user = getUser(userId);
		if (user == null) {
			log.warn("DB error,userid=" + userId+",url="+url);
			return StatusCode.SYSTEM_EXCEPTION.json().msg("系统开小差了，请稍后再试！").toString();
		}
		if (ObjectUtils.isNullOrEmpty(user.getUserId())) {
			log.warn("DB not found user,userid=" + userId+",url="+url);
			return StatusCode.TMSI_NO_MATCH.toJSON("您还未注册，请点击“创建账号”快来注册！");
		}
		if(user.getFlag() == Flag.DELETED){
			log.warn("User already delete,userid=" + userId+",url="+url);
			return StatusCode.TMSI_NO_MATCH.toJSON("您的帐号已被删除，请联系远特卡盟客服！");
		}


		if (user.getUserId() == null) {
			log.warn("DB not found user,userid=" + userId+",url="+url);
			return StatusCode.USER_NOT_FOUND.toJSON();
		}

		if (ObjectUtils.nonEqual(user.getTmsi()+"",tmsiStr)) {
			log.warn("User tmsi not match,userid=" + userId+",url="+url);
			return StatusCode.TMSI_NO_MATCH.toJSON("您的帐号在其它终端上登录,请重新登录");
		}

		final long curTime = System.currentTimeMillis();
		if (user.getLastTime() < (curTime - TMSI_EXPIRED_HOUR * 60 * 60 * 1000)) {
			log.warn("User tmsi expired,userid=" + userId + ",tmsi=" + tmsiStr+",url="+url);
			return StatusCode.TMSI_NO_MATCH.toJSON("用户信息过期,请重新登录");
		}

		/**2018-10-19 区分卡盟——喜牛**/
		String checkVersion;
		final String key;
		if (osType == OsType.ANDROID) {
			key = "ka_meng:androdpackage";
		} else {
			key = "ka_meng:iospackage";
		}
		getVersion(osType,key);
		checkVersion = checkVersion(key,packageName,appVersion,osType,userId);
		if(checkVersion != null){
			return checkVersion;
		}

		User.UserTokenInfo info = user.new UserTokenInfo();
		info.setLastTime(curTime);
		info.setHost(host);
		//info.setUserId(userId);
		info.setLatitude(latitude);
		info.setLongitude(longitude);
		info.setAppVersion(appVersion);
		info.setPackageName(packageName);
		info.setNet(map.get("net"));
		info.setOstype(map.get("osType"));
		info.setOsVersion(map.get("osVersion"));
		info.setPhonetype(map.get("phoneType"));
		info.setApplicationID(map.get("applicationId"));
		info.setImei(imei);
		info.setLocationFlag(Integer.valueOf(locationFlag));
		user.setTokenInfo(info);
		
		// 用户最后时间5分钟更新一次
		if ((curTime - user.getLastTime()) >= 5 * 60 * 1000) {
			updateUserInfo(user.getUserId(),info);
		}

		return user;
	}

	private String checkVersion(final String key, final String packageName, final String appVersion,
								final int osType, final String userId){
		
//		// FIXME 特殊处理20190417,时间过了20190424请删除
//		if(authHeader != null && "1".equals(authHeader.getAppType())){//卡盟
//			if(OsType.IOS == authHeader.getOsType()){
//				if(authHeader.getAppVersion()<2019040300){
//					return StatusCode.UPGRADE.toJSON();
//				}
//				return null;
//			}
//		}
		// 版本校验升级,兼容数据库没有版本信息的时候
		String packInfoReq = redis_hget(key,packageName+appVersion);
		String packInfoNew = redis_hget(key,packageName+LATEST);
		PackageInfo info_req = null;
		PackageInfo info_db = null;
		if(ObjectUtils.nonNullOrEmpty(packInfoReq)){
			info_req = JSONObject.parseObject(packInfoReq,PackageInfo.class);
		}
		if(ObjectUtils.nonNullOrEmpty(packInfoNew)){
			info_db = JSONObject.parseObject(packInfoNew,PackageInfo.class);
		}
		if (info_req == null) {
			log.warn("DB Not found packageinfo,userId="+userId+",packageName=" + packageName+",osType="+osType+",appversion="+appVersion);
			if (info_db == null) {
				// ignore
			} else {
				switch (osType) {
					case OsType.ANDROID:
						if (Integer.valueOf(appVersion) < info_db.getMinRunVersion()) {
							return upgradeAndroid(userId, info_db);
						}
						break;
					case OsType.IOS:
						if (lessThan_ios(appVersion, info_db.getMinRunVersionIOS())) {
							log.warn("ios version unuserd,userid=" + userId + ",appVersion=" + appVersion);
							return StatusCode.UPGRADE.toJSON();
						}
						break;
					default:
						log.error("Unknow client osType,osType=" + osType);
						return StatusCode.FORBID.toJSON();
				}
			}
		}
		// 数据库有版本
		else {
			switch (osType) {
				case OsType.ANDROID:
					// 是否为最新版本
					if (info_req.getTargetVersion() >= info_db.getMinRunVersion()) {
						// ignore
					} else {
						// 最新版本必须升级
						log.warn("android version unuserd,userid=" + userId + ",appVersion=" + appVersion);
						return upgradeAndroid(userId, info_db);
					}
					break;
				case OsType.IOS:// ios 不能使用,返回错误码跳转到appstore
					// 版本相同
					if (appVersion.equals(info_db.getShowVersion())) {
						// ignore
					}
					// 版本小了
					else if (lessThan_ios(appVersion, info_db.getMinRunVersionIOS())) {
						log.warn("ios version unuserd,userid=" + userId + ",appVersion=" + appVersion);
						return StatusCode.UPGRADE.toJSON();
					}
					break;
				default:
					log.error("Unknow client osType,osType=" + osType);
					return StatusCode.FORBID.toJSON();
			}
		}
		return null;
	}

	/**
	 * vertion_req 小于 vertion_db
	 * 
	 * @param vertion_req
	 * @param vertion_db
	 * @return
	 */
	private boolean lessThan_ios(String vertion_req, String vertion_db) {
		// ios 数据库没有数据直接放过
		if("0".equals(vertion_db)){
			return false;
		}
		try {
			String array1[] = vertion_req.split("\\.");
			String array2[] = vertion_db.split("\\.");
			for (int i = 0, j = array1.length; i < j; i++) {
				if (Integer.valueOf(array1[i]) < Integer.valueOf(array2[i])) {
					return true;
				}
				if(Integer.valueOf(array1[i]) > Integer.valueOf(array2[i])){
					return false;
				}
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return false;
	}

	private String upgradeAndroid(String userId, PackageInfo info) {
		JSONObject json = new JSONObject();
		json.put("packageName", info.getPackageName());
		json.put("targetVersion", info.getTargetVersion());
		json.put("showVersion", info.getShowVersion());
		json.put("fileSize", info.getFileSize());
		json.put("filepath", info.getFilepath());
		json.put("minVersion", info.getMinVersion());
		json.put("desc", info.getDesc());
		json.put("pubDate", info.getPubDate());
		json.put("validTag", "2");
		log.info(userId + " package not available," + json);
		return StatusCode.UPGRADE.toDiyJson(true, "data", json.toJSONString());
	}

	private User getUser(final String userId) {
		try (ServerSqlSession session = getSqlDataSource().session();) {
			if (session == null) {
				log.error("DB connection is null");
				return null;
			}
			StringBuilder sb = new StringBuilder(256);
			sb.append("select dealer_id,is_main,createtime,tmsi,osversion,appversion,ostype");
			sb.append(",phonetype,net,citycode,cityname,applicationID,invite_code,user_name");
			sb.append(",last_time,alipay_user_id,alipay_user_name,weixin_user_id,user_type_id");
			sb.append(",host_ip,longitude,latitude,phone,flag,merchant_id,source_type,detail_type");
			sb.append(" from tb_user_client ");
			sb.append(" where userid=? limit 1");
			return session.executeQuery(sb.toString(), new RowMapper<User>(){
				@Override
				public User rowMap(ResultSet rs) throws Exception {
					User u = new User();
					if (rs != null && rs.next()) {
						u.setUserId(userId);
						u.setDealerId(rs.getString("dealer_id"));
						u.setIsMain(rs.getInt("is_main"));
						u.setCreateTime(rs.getLong("createtime"));
						u.setTmsi(rs.getLong("tmsi"));
						u.setOsVersion(rs.getString("osversion"));
						u.setAppVersion(rs.getString("appversion"));
						u.setOsType(rs.getString("ostype"));
						u.setPhoneType(rs.getString("phonetype"));
						u.setNet(rs.getString("net"));
						u.setCityCode(rs.getString("citycode"));
						u.setCityName(rs.getString("cityname"));
						u.setApplicationID(rs.getString("applicationID"));
						u.setInviteCode(rs.getString("invite_code"));
						u.setUserName(rs.getString("user_name"));
						u.setLastTime(rs.getLong("last_time"));
						u.setAlipayUserId(rs.getString("alipay_user_id"));
						u.setAlipayUserName(rs.getString("alipay_user_name"));
						u.setWeixinUserId(rs.getString("weixin_user_id"));
						u.setUserTypeId(rs.getInt("user_type_id"));
						u.setHostIp(rs.getString("host_ip"));
						u.setLongitude(rs.getString("longitude"));
						u.setLatitude(rs.getString("latitude"));
						u.setPhone(rs.getString("phone"));
						u.setFlag(rs.getInt("flag"));
						u.setMerchantId(rs.getString("merchant_id"));
						u.setSourceType(rs.getInt("source_type"));
						u.setDetailType(rs.getInt("detail_type"));
						return u;
					}
					log.warn("DB not found user,userid=" + userId);
					return u;
				}
			}, userId);

		}catch (Exception ex) {
			log.error(ex.getMessage(), ex);
			return null;
		}
	}

	/**将所有版本信息存入redis**/
	private Boolean getVersion(final int osType, final String key) {
		try (ServerSqlSession session = getSqlDataSource().session();) {
			if (session == null) {
				log.error("DB connection is null");
				return null;
			}
			StringBuilder sb = new StringBuilder(256);
			if (osType == OsType.ANDROID) {
				Long ttl = redis_ttl(key);
				if(ttl < 10){
					//无键
					sb.delete(0, sb.length());
					sb.append("select packageName,targetVersion,showVersion,fileSize,logoUrl");
					sb.append(",filepath,minVersion,`desc`,pluginList,pubDate,createTime,crc32");
					sb.append(",updateTime,pid,minRunVersion");
					sb.append(" from packageinfo");
					sb.append(" order by targetVersion desc");

					session.executeQuery(sb.toString(),new RowMapper<PackageInfo>(){
						@Override
						public PackageInfo rowMap(ResultSet rs) throws Exception {
							if (rs != null) {
								List<String> packList = new ArrayList<>();
								while(rs.next()){
									PackageInfo info = new PackageInfo();
									info.setPackageName(rs.getString("packageName"));
									info.setTargetVersion(rs.getInt("targetVersion"));
									info.setShowVersion(rs.getString("showVersion"));
									info.setFileSize(rs.getString("fileSize"));
									info.setLogoUrl(rs.getString("logoUrl"));
									info.setFilepath(rs.getString("filepath"));
									info.setMinVersion(rs.getString("minVersion"));
									info.setDesc(rs.getString("desc"));
									info.setPluginList(rs.getString("pluginList"));
									info.setPubDate(rs.getString("pubDate"));
									info.setCreateTime(rs.getString("createTime"));
									info.setUpdateTime(rs.getString("updateTime"));
									info.setPid(rs.getInt("pid"));
									info.setMinRunVersion(rs.getInt("minRunVersion"));
									info.setCrc32(rs.getString("crc32"));
									String packInfo = JSONObject.toJSONString(info,SerializerFeature.WriteNullStringAsEmpty);
									/**将第一次出现的包名存为最新版本信息**/
									if(!packList.contains(info.getPackageName())){
										redis_hset(key,info.getPackageName()+LATEST,packInfo);
										packList.add(info.getPackageName());
									}
									redis_hset(key,info.getPackageName()+rs.getString("targetVersion"),
											packInfo);
								}
								redis_expire(key,3600);
								return null;
							}
							// 数据库无数据,异常保护
							log.warn("DB not found packageinfo(android)");
							return null;

						}
					});

				}
			}
			else if (osType == OsType.IOS) {
				Long ttl = redis_ttl(key);
				if(ttl < 10){
					sb.delete(0, sb.length());
					sb.append("select id,package_name,target_version,show_version,fileSize");
					sb.append(",`desc`,pubdate,create_time,update_time,min_runversion");
					sb.append(" from tb_packageinfo_ios");
					sb.append(" order by target_version desc ");
					session.executeQuery(sb.toString(),new RowMapper<PackageInfo>(){

						@Override
						public PackageInfo rowMap(ResultSet rs) throws Exception {
							if (rs != null) {
								List<String> packList = new ArrayList<>();
								while(rs.next()){
									PackageInfo info = new PackageInfo();
									info.setPackageName(rs.getString("package_name"));
									info.setTargetVersion(rs.getInt("target_version"));
									info.setShowVersion(rs.getString("show_version"));
									info.setFileSize(rs.getString("fileSize"));
									info.setDesc(rs.getString("desc"));
									info.setPubDate(rs.getString("pubdate"));
									info.setCreateTime(rs.getString("create_time"));
									info.setUpdateTime(rs.getString("update_time"));
									info.setMinRunVersionIOS(rs.getString("min_runversion"));
									String packInfo = JSONObject.toJSONString(info,SerializerFeature.WriteNullStringAsEmpty);
									if(!packList.contains(info.getPackageName())){
										redis_hset(key,info.getPackageName()+LATEST,packInfo);
										packList.add(info.getPackageName());
									}
									redis_hset(key,info.getPackageName()+rs.getString("show_version"),
											packInfo);
								}
								redis_expire(key,3600);
								return null;
							}
							// 数据库无数据,异常保护
							log.warn("DB not found packageinfo(ios)" );
							return null;
						}

					});
				}
			}
			return true;
		}catch (Exception ex) {
			log.error(ex.getMessage(), ex);
			return null;
		}
	}

	/**
	 * 更新用户最后一次信息
	 * 
	 * @param userId
	 * @param info
	 * @return
	 */
	private Boolean updateUserInfo(String userId,final User.UserTokenInfo info) {
		try (ServerSqlSession session = getSqlDataSource().session();) {
			if (session == null) {
				log.error("DB connection is null");
				return false;
			}
			
			if("0".equals(info.getLatitude()) || "0".equals(info.getLongitude())){
				StringBuilder sb = new StringBuilder(256);
				sb.append("update tb_user_client set last_time=? ");
				sb.append(",net=?");
				sb.append(",host_ip=?");
				sb.append(" where userid=?");
				List<Object> list_params = new ArrayList<Object>();
				list_params.add(String.valueOf(info.getLastTime()));
				list_params.add(info.getNet());
				list_params.add(info.getHost());
				list_params.add(userId);
				
				return session.executeUpdate(sb.toString(), list_params)>0;
			}
			else{
				StringBuilder sb = new StringBuilder(256);
				sb.append("update tb_user_client set last_time=? ");
				sb.append(",net=?");
				sb.append(",host_ip=?");
				sb.append(",longitude=?");
				sb.append(",latitude=?");
				sb.append(" where userid=?");
				
				List<Object> list_params = new ArrayList<Object>();
				list_params.add(String.valueOf(info.getLastTime()));
				list_params.add(info.getNet());
				list_params.add(info.getHost());
				list_params.add(info.getLongitude());
				list_params.add(info.getLatitude());
				list_params.add(userId);
				
				return session.executeUpdate(sb.toString(), list_params)>0;
			}
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
			return false;
		}
	}

	public String upgradeAndroid(final int sourceType, final String packageName,
			final int osType, final String userId){
		/**2018-10-19 区分卡盟——喜牛**/
		final String key;
		if (osType == OsType.ANDROID) {
			key = "ka_meng:androdpackage";
		} else {
			key = "ka_meng:iospackage";
		}
		
		saveVersionToRedis(osType,key);
		// 版本校验升级,兼容数据库没有版本信息的时候
		String packInfoNew = redis_hget(key,packageName+LATEST);
		PackageInfo info_db = JSONObject.parseObject(packInfoNew,PackageInfo.class);
		return upgradeAndroid(userId, info_db);
	}
	
	/**将所有版本信息存入redis**/
	private Boolean saveVersionToRedis(final int osType, final String key) {
		try (ServerSqlSession session = getSqlDataSource().session();) {
			if (session == null) {
				log.error("DB connection is null");
				return null;
			}
			StringBuilder sb = new StringBuilder(256);
			if (osType == OsType.ANDROID) {
				Long ttl = redis_ttl(key);
				if(ttl < 10){
					//无键
					sb.delete(0, sb.length());
					sb.append("select packageName,targetVersion,showVersion,fileSize,logoUrl");
					sb.append(",filepath,minVersion,`desc`,pluginList,pubDate,createTime");
					sb.append(",updateTime,pid,minRunVersion,crc32");
					sb.append(" from packageinfo");
					sb.append(" order by targetVersion desc");

					session.executeQuery(sb.toString(),new RowMapper<PackageInfo>(){
						@Override
						public PackageInfo rowMap(ResultSet rs) throws Exception {
							if (rs != null) {
								List<String> packList = new ArrayList<>();
								while(rs.next()){
									PackageInfo info = new PackageInfo();
									info.setPackageName(rs.getString("packageName"));
									info.setTargetVersion(rs.getInt("targetVersion"));
									info.setShowVersion(rs.getString("showVersion"));
									info.setFileSize(rs.getString("fileSize"));
									info.setLogoUrl(rs.getString("logoUrl"));
									info.setFilepath(rs.getString("filepath"));
									info.setMinVersion(rs.getString("minVersion"));
									info.setDesc(rs.getString("desc"));
									info.setPluginList(rs.getString("pluginList"));
									info.setPubDate(rs.getString("pubDate"));
									info.setCreateTime(rs.getString("createTime"));
									info.setUpdateTime(rs.getString("updateTime"));
									info.setPid(rs.getInt("pid"));
									info.setMinRunVersion(rs.getInt("minRunVersion"));
									info.setCrc32(rs.getString("crc32"));
									String packInfo = JSONObject.toJSONString(info,SerializerFeature.WriteNullStringAsEmpty);
									/**将第一次出现的包名存为最新版本信息**/
									if(!packList.contains(info.getPackageName())){
                                        redis_hset(key,info.getPackageName()+LATEST,packInfo);
                                        packList.add(info.getPackageName());
                                    }
									redis_hset(key,info.getPackageName()+rs.getString("targetVersion"),
											packInfo);
								}
								redis_expire(key,3600);
								return null;
							}
                            // 数据库无数据,异常保护
                            log.warn("DB not found packageinfo(android)");
                            return null;

						}
					});

				}
			}
			else if (osType == OsType.IOS) {
				Long ttl = redis_ttl(key);
				if(ttl < 10){
					sb.delete(0, sb.length());
					sb.append("select id,package_name,target_version,show_version,fileSize");
					sb.append(",`desc`,pubdate,create_time,update_time,min_runversion");
					sb.append(" from tb_packageinfo_ios");
					sb.append(" order by target_version desc ");
					session.executeQuery(sb.toString(),new RowMapper<PackageInfo>(){

						@Override
						public PackageInfo rowMap(ResultSet rs) throws Exception {
							if (rs != null) {
								List<String> packList = new ArrayList<>();
								while(rs.next()){
									PackageInfo info = new PackageInfo();
									info.setPackageName(rs.getString("package_name"));
									info.setTargetVersion(rs.getInt("target_version"));
									info.setShowVersion(rs.getString("show_version"));
									info.setFileSize(rs.getString("fileSize"));
									info.setDesc(rs.getString("desc"));
									info.setPubDate(rs.getString("pubdate"));
									info.setCreateTime(rs.getString("create_time"));
									info.setUpdateTime(rs.getString("update_time"));
									info.setMinRunVersionIOS(rs.getString("min_runversion"));
									String packInfo = JSONObject.toJSONString(info,SerializerFeature.WriteNullStringAsEmpty);
									if(!packList.contains(info.getPackageName())){
                                        redis_hset(key,info.getPackageName()+LATEST,packInfo);
                                        packList.add(info.getPackageName());
                                    }
									redis_hset(key,info.getPackageName()+rs.getString("show_version"),
											packInfo);
								}
								redis_expire(key,3600);
								return null;
							}
								// 数据库无数据,异常保护
								log.warn("DB not found packageinfo(ios)" );
								return null;
						}

					});
				}
			}
			return true;
		}catch (Exception ex) {
			log.error(ex.getMessage(), ex);
			return null;
		}
	}
	
	private Boolean testConn() {
		try (ServerSqlSession session = getSqlDataSource().session();) {
			if (session == null) {
				log.error("DB connection is null");
				return false;
			}
			
			return session.executeQuery("select 1", new RowMapper<Boolean>() {
				@Override
				public Boolean rowMap(ResultSet rs) throws Exception {
					return (rs != null && rs.next());
				}
			});
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
			return false;
		}
	}
	

	/**
	 * 客户端 类型
	 * 
	 * @author borya
	 *
	 */
	interface OsType {
		int IOS = 1;
		int ANDROID = 2;
	}
	
	public Long redis_ttl(final String key){
		try (ServerRedisSession session = getSessionFactory().session()){
			return  session.ttl(key);
		} catch (Exception e) {
			log.error(e.getMessage()+",operation failed :"+key,e);
			return null;
		}
	}

	public boolean redis_hset(final String key,String field,String value){
		try (ServerRedisSession session = getSessionFactory().session()){
			return  (session.hset(key, field, value) != null);
		} catch (Exception e) {
			log.error(e.getMessage()+",operation failed :"+key,e);
			return false;
		}
	}


	public String redis_hget(final String key,String field){
		try (ServerRedisSession session = getSessionFactory().session()){
			return session.hget(key, field);
		} catch (Exception e) {
			log.error(e.getMessage()+",operation failed :"+key,e);
			return null;
		}
	}

	public boolean redis_expire(String key,int seconds){
		try (ServerRedisSession session = getSessionFactory().session()){
			return (session.expire(key, seconds) != null);
		} catch (Exception e) {
			log.error(e.getMessage(),e);
			return false;
		}
	}

	public String redis_get(final String key){
		try (ServerRedisSession session = getSessionFactory().session()){
			return session.get(key);
		} catch (Exception e) {
			log.error(e.getMessage()+",operation failed :"+key,e);
			return null;
		}
	}
}